/**
 * @file widget.h
 * @brief 计算器应用程序的头文件
 * @details 定义了Widget类，包含计算器的所有功能接口
 *          支持基本四则运算、小数运算和括号运算
 *          使用栈结构实现中缀表达式求值算法
 * @author 计算器开发者
 * @date 2024
 */

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QStack>
#include <string.h>
#include <QChar>
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui
{
    class Widget;
}
QT_END_NAMESPACE

/**
 * @brief 计算器主窗口类
 * @details 继承自QWidget，实现了一个功能完整的计算器
 *          包含数字输入、运算符处理、表达式计算等功能
 *          使用栈结构实现中缀表达式求值算法
 *
 * 主要功能：
 * - 支持基本四则运算（加、减、乘、除）
 * - 支持小数运算
 * - 支持括号运算和优先级处理
 * - 实时显示输入和计算结果
 * - 完善的错误处理机制
 */
class Widget : public QWidget
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param parent 父窗口指针，默认为nullptr
     * @details 初始化计算器界面，设置样式和布局
     *          包括窗口标题、图标、背景色和各种按钮样式
     */
    Widget(QWidget *parent = nullptr);

    /**
     * @brief 析构函数
     * @details 释放UI资源，防止内存泄漏
     */
    ~Widget();

private slots:
    // ==================== 数字按钮事件处理 ====================

    /**
     * @brief 数字1按钮点击事件处理
     * @details 如果当前显示为0，则替换为1；否则在末尾添加1
     */
    void on_oneBtn_clicked();

    /**
     * @brief 数字2按钮点击事件处理
     * @details 如果当前显示为0，则替换为2；否则在末尾添加2
     */
    void on_twoBtn_clicked();

    /**
     * @brief 数字3按钮点击事件处理
     * @details 如果当前显示为0，则替换为3；否则在末尾添加3
     */
    void on_threeBtn_clicked();

    /**
     * @brief 数字4按钮点击事件处理
     * @details 如果当前显示为0，则替换为4；否则在末尾添加4
     */
    void on_fourBtn_clicked();

    /**
     * @brief 数字5按钮点击事件处理
     * @details 如果当前显示为0，则替换为5；否则在末尾添加5
     */
    void on_fiveBtn_clicked();

    /**
     * @brief 数字6按钮点击事件处理
     * @details 如果当前显示为0，则替换为6；否则在末尾添加6
     */
    void on_sixBtn_clicked();

    /**
     * @brief 数字7按钮点击事件处理
     * @details 如果当前显示为0，则替换为7；否则在末尾添加7
     */
    void on_sevenBtn_clicked();

    /**
     * @brief 数字8按钮点击事件处理
     * @details 如果当前显示为0，则替换为8；否则在末尾添加8
     */
    void on_eightBtn_clicked();

    /**
     * @brief 数字9按钮点击事件处理
     * @details 如果当前显示为0，则替换为9；否则在末尾添加9
     */
    void on_nineBtn_clicked();

    /**
     * @brief 数字0按钮点击事件处理
     * @details 如果当前不是0，则在末尾添加0；否则保持0不变
     */
    void on_zeroBtn_clicked();

    // ==================== 运算符和括号按钮事件处理 ====================

    /**
     * @brief 左括号按钮点击事件处理
     * @details 先处理连续操作符，然后添加左括号
     */
    void on_leftBtn_clicked();

    /**
     * @brief 右括号按钮点击事件处理
     * @details 先处理连续操作符，然后添加右括号
     */
    void on_rightBtn_clicked();

    /**
     * @brief 加法按钮点击事件处理
     * @details 先处理连续操作符，然后添加加号
     */
    void on_addBtn_clicked();

    /**
     * @brief 减法按钮点击事件处理
     * @details 先处理连续操作符，然后添加减号
     */
    void on_subBtn_clicked();

    /**
     * @brief 乘法按钮点击事件处理
     * @details 先处理连续操作符，然后添加乘号
     */
    void on_mulBtn_clicked();

    /**
     * @brief 除法按钮点击事件处理
     * @details 先处理连续操作符，然后添加除号
     */
    void on_divBtn_clicked();

    // ==================== 功能按钮事件处理 ====================

    /**
     * @brief 清除按钮点击事件处理
     * @details 清空表达式，重置显示为0，清空历史记录
     */
    void on_clsBtn_clicked();

    /**
     * @brief 删除按钮点击事件处理
     * @details 删除最后一个字符，如果只剩一个字符则重置为0
     */
    void on_deleteBtn_clicked();

    /**
     * @brief 等号按钮点击事件处理
     * @details 执行表达式计算，使用栈结构实现中缀表达式求值算法
     *          支持四则运算、小数运算、括号运算和优先级处理
     */
    void on_equalBtn_clicked();

    /**
     * @brief 小数点按钮点击事件处理
     * @details 先处理连续操作符，然后添加小数点
     */
    void on_floatBtn_clicked();

    /**
     * @brief 显示文本变化事件处理
     * @param arg1 变化后的文本内容
     * @details 当显示文本发生变化时，确保表达式不为空
     *          如果表达式为空，则设置为"0"
     */
    void on_show_textChanged(const QString &arg1);

private:
    Ui::Widget *ui;           ///< UI界面指针，指向Qt Designer生成的界面类
    QString expression = "0"; ///< 存储当前表达式的字符串，初始值为"0"

    // ==================== 私有辅助函数 ====================

    /**
     * @brief 获取操作符的优先级
     * @param a 操作符字符
     * @return 优先级数值（数值越大优先级越高）
     * @details 用于表达式求值时的操作符优先级比较
     *
     * 优先级规则：
     * - 加减法：优先级1（最低）
     * - 乘除法：优先级2（中等）
     * - 幂运算：优先级3（较高）
     * - 左括号：优先级4（最高，用于括号内运算）
     */
    int Priority(char a);

    /**
     * @brief 执行一次运算操作
     * @param s_num 数字栈的引用
     * @param s_opt 操作符栈的引用
     * @details 从栈中弹出两个数字和一个操作符，执行运算后将结果压回数字栈
     *          支持加法、减法、乘法、除法四种运算
     *          包含除零检查和错误处理
     */
    void calcOnce(QStack<double> &s_num, QStack<char> &s_opt);

    /**
     * @brief 处理连续操作符输入
     * @details 当用户连续输入操作符时，自动删除前一个操作符
     *          避免表达式出现连续操作符的情况
     *          例如：1++2 会被处理成 1+2
     */
    void inputContinuousOpt();
//    void inputContinuousBracket(char bra);

    /**
     * @brief 验证字符串是否为有效数字
     * @param str 待验证的字符串
     * @return 如果是有效数字返回true，否则返回false
     * @details 支持负数和小数格式验证
     * @note 此函数目前已被注释掉，不再使用
     */
    bool isDigital(QString str);
    bool checkBracketOperatorValid(const QString &expr, QString &errMsg);
};

#endif // WIDGET_H
